package com.youyun56.gps.schedual;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.youyun56.pojo.Car;


public class GPSClaimer implements Runnable{
	private Socket socket;
	private Log log = LogFactory.getLog(GPSClaimer.class);
	private final BufferedReader in;
	private final PrintWriter out;
	private Semaphore semp = new Semaphore(1);
	private LinkedBlockingQueue<Car> cars;
	private ServiceStatusType status = ServiceStatusType.active;
	private String requestMobile = null;
	public GPSClaimer(LinkedBlockingQueue<Car> cars) throws UnknownHostException, IOException {
		// TODO Auto-generated constructor stub
		this.cars = cars;
		socket = new Socket(GPSFactory.getIP(),GPSFactory.getPort());
		this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		this.out = new PrintWriter(socket.getOutputStream());		
		out.print(GPSFactory.login);
		out.flush();
		String line = in.readLine();			
		if(MessageAnalysis.loginSuccess(line)){
			log.info("Socket building Successful....");
			new Thread(new Runnable() {
				
				public void run() {
					// TODO Auto-generated method stub					
					while(status != ServiceStatusType.down){
						try {
							String line = in.readLine();
							String[] infos = MessageAnalysis.infos(line); 
							if(infos[1].indexOf(requestMobile) == -1){
								log.info(String.format("REQUEST %s BACK %s", requestMobile,infos[1]));
								continue;
							}
							if(infos[0].equals(GPSFactory.gpsSuccessHead)){
								log.info(String.format("gps success: %s", line));
								continue;
							}else if(infos[0].equals(GPSFactory.gpsInfoHead)){
								if(infos.length > 6)
								log.info(line);
								String x = infos[4];
								String y = infos[5];
								URL url = new URL(GPSFactory.getGeocoding().replace("#X", y).replace("#Y", x));
								InputStreamReader isr = new InputStreamReader(url.openStream());
								BufferedReader br = new BufferedReader(isr);
								String lin = null;
								StringBuffer sb = new StringBuffer();
								while((lin = br.readLine()) != null){
									sb.append(lin);
									log.info(lin);
								}
								isr.close();
								JSONObject o = JSONObject.fromObject(sb.toString());
								//log.info(o);
								doMessage(o, sb.toString());
								semp.release();
							}else{
								log.error(String.format("unexcept info: %s", line));
							}
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			}).start();
			log.info("启动成功");
		}else{
			log.error("启动失败...");
		}
		
	}

	public void run() {
		// TODO Auto-generated method stub
		while(status != ServiceStatusType.down){
			if(status == ServiceStatusType.suspended){
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				continue;
			}
			
//			lock.lock();			
			try {
				log.info("trylock");
				semp.acquire();
				log.info("lock");
				requestMobile = cars.take().getCarMobile();
				out.print(GPSFactory.gps(requestMobile));
				out.flush();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				log.error(e);
			}
		}
	}
	
	public void addCars(List<Car> cars){
		this.cars.addAll(cars);
	}
	
	
	
	
	public void doMessage(JSONObject o,String line){
		
		GoogleStatus status = GoogleStatus.valueOf(o.getString("status"));		
		if(status == GoogleStatus.OK){
			JSONArray array = o.getJSONArray("results");
			if(array.size() >= 3){
				JSONObject address = (JSONObject) array.get(0);
				log.info(address);
				JSONArray addresses = address.getJSONArray("address_components");
				int len = addresses.size();
				StringBuffer local = new StringBuffer();
				String city = null;
				for(int i = len - 1; i >=0 ;i--){
					JSONObject point = (JSONObject) addresses.get(i);
					String longName = point.getString(GoogleAddress.long_name);
					String type = (String) point.getJSONArray(GoogleAddress.types).get(0);
					if(type.equals(GoogleAddress.locality)){
						city = longName; 
						local.append(longName);
					}else if(type.equals(GoogleAddress.sublocality)){
						local.append(longName);
						break;
					}else{
						local.append(longName);
					}
				}
				log.info(String.format("City : %s ,LOCAL : %s", city,local));
			}
		}else if(status == GoogleStatus.ZERO_RESULTS){
			log.error(line = " | " + GoogleStatus.OVER_QUERY_LIMIT.name());
		}else if(status == GoogleStatus.OVER_QUERY_LIMIT){
			log.error(line = " | " + GoogleStatus.OVER_QUERY_LIMIT.name());
		}
		
	}

	public ServiceStatusType getStatus() {
		return status;
	}

	public void setStatus(ServiceStatusType status) {
		this.status = status;
	}
	
	public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
		LinkedBlockingQueue<Car> list = new LinkedBlockingQueue<Car>();
		list.add(new Car(1L,"13313911728"));
		list.add(new Car(2L,"13313916998"));
		list.add(new Car(3L,"18965353393"));
		list.add(new Car(4L,"13313915980"));
		list.add(new Car(5L,"13313916998"));
		Thread thread = new Thread(new GPSClaimer(list));
		thread.start();
		thread.join();
		
		System.out.println();
	}

}
